import 'dart:async';
import 'dart:io';
import 'package:assets_audio_player/assets_audio_player.dart';
import 'package:e_reception_flutter/common_widgets/common_confirm_cancel_dialog/common_confirm_cancel_dialog.dart';
import 'package:e_reception_flutter/common_widgets/common_list_page_widget/common_list_page_widget.dart';
import 'package:e_reception_flutter/net/net_api.dart';
import 'package:e_reception_flutter/singleton/theme_repository/theme_repository.dart';
import 'package:e_reception_flutter/singleton/user_repository/user_repository.dart';
import 'package:e_reception_flutter/ui/building_index/edit_delete_pop_menu_widget.dart';
import 'package:e_reception_flutter/ui/new_terminal/bg_music/bg_terminal_music_list_view_model.dart';
import 'package:e_reception_flutter/ui/new_terminal/bg_music/notify_bg_music_to_stop_event.dart';
import 'package:e_reception_flutter/ui/new_terminal/bg_music/position_seek_widget.dart';
import 'package:e_reception_flutter/ui/new_terminal/bg_music/refresh_terminal_bg_music_list_event.dart';
import 'package:e_reception_flutter/ui/new_terminal/bg_music/terminal_bg_music_name_list_event.dart';
import 'package:e_reception_flutter/utils/router_utils.dart';
import 'package:e_reception_flutter/utils/screen_utils.dart';
import 'package:e_reception_flutter/utils/vg_http_utils.dart';
import 'package:e_reception_flutter/utils/vg_hud_utils.dart';
import 'package:e_reception_flutter/vg_widgets/vg_dialog_widget/general_animation_dialog.dart';
import 'package:e_reception_flutter/vg_widgets/vg_mixin/navigator_page_mixin.dart';
import 'package:e_reception_flutter/vg_widgets/vg_place_holder_status_widget/vg_place_holder_status_widget.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:vg_base/vg_arch_lib.dart';
import 'package:vg_base/vg_evnet_bus_lib.dart';
import 'package:vg_base/vg_http_lib.dart';
import 'bean/bg_terminal_music_list_response_bean.dart';
import 'change_to_recommend_or_my_list_page_event.dart';
import 'local_music_page.dart';

/// 背景音乐列表
class BgTerminalMusicListPage extends StatefulWidget {
  ///路由名称
  static const String ROUTER = "BgTerminalMusicListPage";
  final String terminalName;
  final String hsn;
  final String hsns;
  const BgTerminalMusicListPage({Key key,this.terminalName, this.hsn, this.hsns}):super(key: key);

  @override
  BgTerminalMusicListPageState createState() => BgTerminalMusicListPageState();

}

class BgTerminalMusicListPageState
    extends BaseState<BgTerminalMusicListPage>
    with AutomaticKeepAliveClientMixin,
        NavigatorPageMixin,
        SingleTickerProviderStateMixin {

  BgTerminalMusicListViewModel _viewModel;
  StreamSubscription _terminalBgMusicUpdateStreamSubscription;
  StreamSubscription _terminalCountUpdateStreamSubscription;
  StreamSubscription _notifyBgMusicToStopStreamSubscription;

  CommonListPageWidgetState<MusicListBean, BgTerminalMusicListResponseBean>
  mState;
  List<MusicListBean> mMusicList;


  AssetsAudioPlayer _assetsAudioPlayer;
  final List<StreamSubscription> _subscriptions = [];
  bool _isPlaying = false;
  Audio _playingAudio;
  String _currentMusicId;
  AnimationController _controller;
  @override
  void initState() {
    super.initState();
    mMusicList = new List();
    _viewModel = BgTerminalMusicListViewModel(this);
    _viewModel?.getBgMusicList(widget?.hsn);
    _terminalBgMusicUpdateStreamSubscription =
        VgEventBus.global.on<RefreshTerminalBgMusicListEvent>()?.listen((event) {
          _viewModel?.getBgMusicList(widget?.hsn);
          mState?.viewModel?.refresh();
        });

    _assetsAudioPlayer = AssetsAudioPlayer.newPlayer();
    _subscriptions.add(_assetsAudioPlayer.onReadyToPlay.listen((event) {
      VgHudUtils.hide(context);
    }));
    _subscriptions.add(_assetsAudioPlayer.playlistAudioFinished.listen((data) {
      print('playlistAudioFinished : $data');
    }));
    _subscriptions.add(_assetsAudioPlayer.audioSessionId.listen((sessionId) {
      print('audioSessionId : $sessionId');
    }));
    _subscriptions.add(_assetsAudioPlayer.isPlaying.listen((isPlay) {
      setState(() {
        _isPlaying = isPlay??false;
      });
    }));
    _subscriptions.add(_assetsAudioPlayer.current.listen((playing) {
      if(playing != null){
        setState(() {
          _currentMusicId = playing?.audio?.audio?.metas?.id??"";
          print('_currentMusicId : $_currentMusicId');
        });
      }
    }));
    _controller = AnimationController(duration: const Duration(seconds: 1), vsync: this);
    _controller.addStatusListener((status) {
      if (status == AnimationStatus.completed) {
        //动画从 controller.forward() 正向执行 结束时会回调此方法
        //重置起点
        _controller.reset();
        //开启
        _controller.forward();
      } else if (status == AnimationStatus.dismissed) {
        //动画从 controller.reverse() 反向执行 结束时会回调此方法
      } else if (status == AnimationStatus.forward) {
        //执行 controller.forward() 会回调此状态
      } else if (status == AnimationStatus.reverse) {
        //执行 controller.reverse() 会回调此状态
      }
    });
    _notifyBgMusicToStopStreamSubscription =
        VgEventBus.global.on<NotifyBgMusicToStopEvent>()?.listen((event) {
          if((event.page == 1 || event.page == 2) && _isPlaying){
            _assetsAudioPlayer.pause();
            _controller.stop();
          }
        });
  }

  @override
  void dispose() {
    _terminalBgMusicUpdateStreamSubscription?.cancel();
    _terminalCountUpdateStreamSubscription?.cancel();
    _notifyBgMusicToStopStreamSubscription?.cancel();
    _assetsAudioPlayer.dispose();
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    super.build(context);
    return Container(
      color: ThemeRepository.getInstance().getBgOrSplitColor_191E31(),
      child: Stack(
        children: [
          Column(
            children: [
              _toBgMusicStatusWidget(),
              Expanded(child: _toPlaceHolderWidget()),
            ],
          ),
          _toUploadWidget(),
        ],
      ),
    );
  }

  Widget _toPlaceHolderWidget() {
    return ValueListenableBuilder(
        valueListenable: _viewModel?.statusTypeValueNotifier,
        builder:
            (BuildContext context, PlaceHolderStatusType value, Widget child) {
          return VgPlaceHolderStatusWidget(
            loadingStatus: value == PlaceHolderStatusType.loading,
            errorStatus: value == PlaceHolderStatusType.error,
            emptyStatus: value == PlaceHolderStatusType.empty,
            errorOnClick: () => _viewModel
                .getBgMusicList(widget?.hsn),
            loadingOnClick: () => _viewModel
                .getBgMusicList(widget?.hsn),
            child: child,
          );
        },
        child:  _toListPage());
  }

  ///上传文件布局
  Widget _toUploadWidget(){
    return Visibility(
      visible: Platform.isAndroid,
      child: Positioned(
        bottom: 50 + ScreenUtils.getBottomBarH(context),
        left: (ScreenUtils.screenW(context) - 148)/2,
        child: GestureDetector(
          behavior: HitTestBehavior.opaque,
          onTap: throttle(()  async {
            List<String> musicNameList = mMusicList.map((e) => e.mname).toList();
            LocalMusicPage.navigatorPush(context, widget?.hsn, widget?.hsns, musicNameList);
            await Future.delayed(Duration(milliseconds: 2000));
          }),
          child: Container(
            width: 148,
            height: 40,
            alignment: Alignment.center,
            decoration: BoxDecoration(
              color: ThemeRepository.getInstance().getPrimaryColor_1890FF(),
              borderRadius: BorderRadius.circular(24),
            ),
            child: Row(
              mainAxisSize: MainAxisSize.min,
              mainAxisAlignment: MainAxisAlignment.center,
              children: [
                Image.asset("images/add_icon.png",width: 14,color: Colors.white,),
                SizedBox(width: 4,),
                Text(
                  "添加本地音乐",
                  style: TextStyle(
                      color: Colors.white,
                      fontSize: 15,
                      height: 1.2,
                      fontWeight: FontWeight.w600
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  /// 函数节流
  ///
  /// [func]: 要执行的方法
  Function throttle(
      Future Function() func,
      ) {
    if (func == null) {
      return func;
    }
    bool enable = true;
    Function target = () {
      if (enable == true) {
        enable = false;
        func().then((_) {
          enable = true;
        });
      }
    };
    return target;
  }



  Widget _toListPage(){
    return CommonListPageWidget<MusicListBean,
        BgTerminalMusicListResponseBean>(
      enablePullUp: false,
      enablePullDown: false,
      queryMapFunc: (int page) => {
        "authId": UserRepository.getInstance().authId ?? "",
        "hsn": widget?.hsn ?? "",
      },
      parseDataFunc: (VgHttpResponse resp) {
        return BgTerminalMusicListResponseBean.fromMap(resp?.data);
      },
      stateFunc: (CommonListPageWidgetState<MusicListBean,
          BgTerminalMusicListResponseBean>
      state) {
        mState = state;
      },
      itemBuilder: (BuildContext context, int index, itemBean) {
        return toDraggable(index, itemBean);
      },
      separatorBuilder: (context, int index, _) {
        return SizedBox(height: 0);
      },
      netUrl: NetApi.GET_BG_MUSIC_LIST,
      httpType: VgHttpType.get,
      needBottomSaveWidget: true,
      bottomExtraHeight: 70,
    );

  }

  ///背景音乐状态
  ///flg   00开启 01关闭
  Widget _toBgMusicStatusWidget(){
    return ValueListenableBuilder(
        valueListenable: _viewModel?.musicListAndFlagValueNotifier,
        builder:
            (BuildContext context, MusicListDataBean listDataBean, Widget child) {
          if(listDataBean != null && listDataBean?.musicList != null){
            mMusicList.clear();
            mMusicList.addAll(listDataBean?.musicList);
            List<String> musicNameList = mMusicList.map((e) => e.mname).toList();
            VgEventBus.global.send(new TerminalBgMusicNameListEvent(musicNameList: musicNameList));
          }
          return Container(
            height: 50,
            alignment: Alignment.centerLeft,
            color: ThemeRepository.getInstance().getCardBgColor_21263C(),
            child: Row(
              children: [
                SizedBox(width: 15,),
                Text(
                  (listDataBean?.isOpen()??false)?"背景音乐已开启":"背景音乐已关闭",
                  style: TextStyle(
                    fontSize: 15,
                    color: (listDataBean?.isOpen()??false)?ThemeRepository.getInstance().getPrimaryColor_1890FF():ThemeRepository.getInstance().getMinorRedColor_F95355(),
                  ),
                ),
                Spacer(),
                GestureDetector(
                  behavior: HitTestBehavior.opaque,
                  onTap: (){
                    _viewModel.openOrCloseBgMusic(
                        context,
                        widget?.hsn,
                        (listDataBean?.isOpen()??false)?"01":"00", callback: (){
                      if(listDataBean != null && listDataBean.musicList.isEmpty){
                        VgEventBus.global.send(new ChangeToRecommendOrMyListPageEvent(1));
                      }
                    });
                  },
                  child: Container(
                    height: 50,
                    width: 66,
                    alignment: Alignment.center,
                    child: Image.asset(
                      (listDataBean?.isOpen()??false)
                          ? "images/icon_open.png"
                          :"images/icon_close.png",
                      width: 36,
                    ),
                  ),
                ),
              ],
            ),
          );
        });
  }

  Widget toDraggable(int index, MusicListBean itemBean){
    return LongPressDraggable<int>(
        data: index,
        maxSimultaneousDrags: 1,
        childWhenDragging: Opacity(
          opacity: 0.5,
          child: _toListItemWidget(index, itemBean),
        ),
        feedback: Material(
          child: Container(
            height: 70,
            decoration: BoxDecoration(
                boxShadow: [
                  BoxShadow(
                      color: Colors.white.withOpacity(0.5),
                      blurRadius: 5
                  )
                ]
            ),
            width: ScreenUtils.screenW(context),
            child: _toListItemWidget(index, itemBean),
          ),
        ),
        child: DragTarget<int>(
          onAccept: (int start){
            _processState(start, index);
          },
          onWillAccept: (int fromIndex) {
            return true;
          },
          builder: (BuildContext context, candidateData,
              List<dynamic> rejectedData) {
            return _toListItemWidget(index, itemBean);
          },
        ));
  }

  Widget _toListItemWidget(int index, MusicListBean itemBean){
    return GestureDetector(
      behavior: HitTestBehavior.opaque,
      onTap: (){
        openPlayer(itemBean);
      },
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Container(
            height: 70,
            alignment: Alignment.centerLeft,
            color: ThemeRepository.getInstance().getCardBgColor_21263C(),
            child: Row(
              children: [
                _toMusicLogoWidget(itemBean),
                Column(
                  crossAxisAlignment: CrossAxisAlignment.start,
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Container(
                      width: ScreenUtils.screenW(context) - 140,
                      alignment: Alignment.centerLeft,
                      child: Text(
                        itemBean?.mname??"-",
                        maxLines: 1,
                        overflow: TextOverflow.ellipsis,
                        style: TextStyle(
                            fontSize: 15,
                            color: ThemeRepository.getInstance().getTextColor_D0E0F7()
                        ),
                      ),
                    ),
                    SizedBox(height: 2,),
                    Text(
                      itemBean?.getTimeAndSize(),
                      style: TextStyle(
                          fontSize: 12,
                          color: ThemeRepository.getInstance().getHintGreenColor_5E687C()
                      ),
                    ),
                  ],
                ),
                Spacer(),
                GestureDetector(
                  behavior: HitTestBehavior.opaque,
                  onTapUp: (details){
                    showAnimationDialog(
                        context: context,
                        transitionType: TransitionType.fade,
                        barrierColor: Color(0x00000001),
                        transitionDuration: Duration(milliseconds: 100),
                        builder: (context) {
                          return EditDeletePopMenuWidget(
                            items: ["移除",],
                            details: details,
                            bgColor: Color(0XFF303546),
                            textColor: ThemeRepository.getInstance().getTextColor_D0E0F7(),
                            onClickItem: (content) async{
                              RouterUtils.pop(context);
                              if (content == "移除") {
                                bool result = await CommonConfirmCancelDialog.navigatorPushDialog(context,
                                    title: "提示",
                                    content: "确定移除该背景音乐？",
                                    cancelText: "取消",
                                    confirmText: "确认",
                                    confirmBgColor:
                                    ThemeRepository.getInstance().getMinorRedColor_F95355());
                                if (result ?? false) {
                                  if(_isPlaying && itemBean.id == _currentMusicId){
                                    _assetsAudioPlayer.pause();
                                    _controller.stop();
                                  }
                                  _viewModel.deleteBgByHsn(context, widget?.hsn, itemBean?.id);
                                }
                              }
                            },
                          );
                        }
                    );
                  },
                  child: Container(
                    padding: EdgeInsets.symmetric(horizontal: 15),
                    width: 50,
                    height: 70,
                    alignment: Alignment.center,
                    child: Image.asset(
                      "images/icon_more_vertical.png",
                      width: 20,
                      height: 20,
                    ),
                  ),
                ),
              ],
            ),
          ),
          _toSeekWidget(itemBean),
        ],
      ),
    );
  }

  void _processState(int start, int end) {
    print("拖拽调整： $start - $end");
    List list = mState?.data;
    if (list == null || list.isEmpty) {
      return;
    }
    var removeItem = list.removeAt(start);
    list.insert(end, removeItem);
    mState?.setState(() {});
    String ids = list.map((e) => e.id).toList().join(",");
    _viewModel.modifyOrder(context, ids, widget?.hsn);
  }

  Widget _toMusicLogoWidget(MusicListBean itemBean){
    if(_isPlaying && itemBean.id == _currentMusicId){
      _controller.forward();
      return Container(
        width: 64,
        alignment: Alignment.center,
        child: RotationTransition(
          alignment: Alignment.center,
          turns: _controller,
          child: Image.asset(
            "images/icon_music_play.png",
            width: 46,
            height: 46,
          ),
        ),
      );
    }else{
      return Container(
        width: 64,
        alignment: Alignment.center,
        child: Image.asset(
          "images/icon_music_play.png",
          width: 34,
          height: 34,
        ),
      );
    }
  }

  Widget _toSeekWidget(MusicListBean itemBean){
    return Visibility(
      visible: _isPlaying && itemBean.id == _currentMusicId,
      child: Container(
        height: 50,
        alignment: Alignment.center,
        color: ThemeRepository.getInstance().getCardBgColor_21263C(),
        child: _assetsAudioPlayer.builderRealtimePlayingInfos(
            builder: (context, infos) {
              if (infos == null) {
                return SizedBox();
              }
              return Column(
                children: [
                  PositionSeekWidget(
                    currentPosition: infos.currentPosition,
                    duration: infos.duration,
                    seekTo: (to) {
                      _assetsAudioPlayer.seek(to);
                    },
                  ),
                  Container(
                    padding: EdgeInsets.symmetric(horizontal: 15),
                    child: Row(
                      mainAxisAlignment: MainAxisAlignment.start,
                      children: [
                        Text(
                          durationToString(infos.currentPosition),
                          style: TextStyle(
                              fontSize: 10,
                              color: Colors.white
                          ),
                        ),
                        Spacer(),
                        Text(
                          durationToString(infos.duration),
                          style: TextStyle(
                              fontSize: 10,
                              color: ThemeRepository.getInstance().getHintGreenColor_5E687C()
                          ),
                        ),
                      ],
                    ),
                  )
                ],
              );
            }),
      ),
    );
  }

  String durationToString(Duration duration) {
    String twoDigits(int n) {
      if (n >= 10) return "$n";
      return "0$n";
    }

    String twoDigitMinutes =
    twoDigits(duration.inMinutes.remainder(Duration.minutesPerHour));
    String twoDigitSeconds =
    twoDigits(duration.inSeconds.remainder(Duration.secondsPerMinute));
    return "$twoDigitMinutes:$twoDigitSeconds";
  }

  void openPlayer(MusicListBean itemBean) async {
    VgEventBus.global.send(new NotifyBgMusicToStopEvent(0));
    if(itemBean?.id == _currentMusicId){
      if(_isPlaying){
        _assetsAudioPlayer.pause();
      }else{
        _assetsAudioPlayer.play();
      }
      return;
    }
    VgHudUtils.show(context, "加载中");
    _playingAudio = Audio.network(
        itemBean.murl,
        metas: Metas(
          id: itemBean.id,
          title: itemBean.mname,
          artist: itemBean.author,
          album: itemBean.author,
        ),
        cached: true
    );
    setState(() {});
    try {
      await _assetsAudioPlayer.open(
        _playingAudio,
        autoStart: true,
        showNotification: false,
        playInBackground: PlayInBackground.disabledRestoreOnForeground,
        audioFocusStrategy: AudioFocusStrategy.request(
            resumeAfterInterruption: true,
            resumeOthersPlayersAfterDone: true),
        headPhoneStrategy: HeadPhoneStrategy.pauseOnUnplug,
      );
    } catch (e) {
      print(e);
    }
  }

  @override
  bool get wantKeepAlive => true;
}
